/*
 * Copyright 2007 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.sf.hibernate4gwt.core.beanlib.clone;

import net.sf.beanlib.hibernate.UnEnhancer;
import net.sf.beanlib.hibernate3.Hibernate3JavaBeanReplicator;
import net.sf.beanlib.spi.BeanTransformerSpi;
import net.sf.beanlib.spi.replicator.BeanReplicatorSpi;
import net.sf.hibernate4gwt.core.beanlib.IClassMapper;
import net.sf.hibernate4gwt.core.beanlib.merge.MergeClassBeanReplicator;

/**
 * Bean replicator with different from and to classes for clone operation
 * @author bruno.marchesson
 *
 */
public class CloneClassBeanReplicator extends Hibernate3JavaBeanReplicator
{
	//---
	// Attributes
	//---
	/**
	 * The class mapper (can be null)
	 */
	private IClassMapper _classMapper;
	
	//----
	// Factory
	//----
	public static final Factory factory = new Factory();
	
    /**
     * Factory for {@link MergeClassBeanReplicator}
     * 
     * @author bruno.marchesson
     */
    public static class Factory implements BeanReplicatorSpi.Factory {
        private Factory() {}
        
        public CloneClassBeanReplicator newBeanReplicatable(BeanTransformerSpi beanTransformer) {
            return new CloneClassBeanReplicator(beanTransformer);
        }
    }
    
    public static CloneClassBeanReplicator newBeanReplicatable(BeanTransformerSpi beanTransformer) {
        return factory.newBeanReplicatable(beanTransformer);
    }
    
    //----
	// Constructor
	//----
    protected CloneClassBeanReplicator(BeanTransformerSpi beanTransformer) 
    {
        super(beanTransformer);
    }
    
    //----
    // Properties
    //----
    /**
	 * @return the Class Mapper
	 */
	public IClassMapper getClassMapper() {
		return _classMapper;
	}

	/**
	 * @param mapper the classMapper to set
	 */
	public void setClassMapper(IClassMapper mapper) {
		_classMapper = mapper;
	}

	//----
    // Override
    //----
    @Override
    protected <T extends Object> T createToInstance(Object from, java.lang.Class<T> toClass) 
    			throws InstantiationException ,IllegalAccessException ,SecurityException ,NoSuchMethodException 
    {   	
    //	Class mapper indirection
    //
        if (_classMapper != null)
        {
        	Class<T> targetClass = _classMapper.getTargetClass(UnEnhancer.unenhanceClass(toClass)); 
        	
        	if (targetClass != null)
        	{
        		toClass = targetClass;
        	}
        }
        return super.createToInstance(from, toClass);
    }
}
